/**************************************************************************************
*
*	Copyright (C) 2010 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	ShaderConstant.cpp
*
*	Comments	-	See ShaderConstant.h
*
**************************************************************************************/

#ifdef __PSX_WINDOWS_WINDOW

#include "../Include/ShaderConstant.h"
#include "../Include/GraphicsResourceManager.h"

namespace Pulse
{
	ShaderConstant::ShaderConstant( const CHAR *pName, EShaderConstantType::Type type, SIZE_T count, void *pDefaultData )
		: m_name( pName ), m_dataCount( count ), m_type( type )
	{
		SIZE_T dataTypeSize;
		
		switch( type )
		{
		case EShaderConstantType::FLOAT:
			m_pData = new FLOAT[count];
			m_pDefaultData = new FLOAT[count];
			dataTypeSize = sizeof(FLOAT);
			break;
		case EShaderConstantType::INT:
			m_pData = new int[count];
			m_pDefaultData = new int[count];
			dataTypeSize = sizeof(int);
			break;
		case EShaderConstantType::BOOL:
			m_pData = new bool[count];
			m_pDefaultData = new bool[count];
			dataTypeSize = sizeof(bool);
			 break;
		}
		
		m_size = dataTypeSize * count;
		
		if ( pDefaultData && count )
		{
			PSX_MemCopy( m_pData, pDefaultData, count * dataTypeSize );
			PSX_MemCopy( m_pDefaultData, pDefaultData, count * dataTypeSize );
		}
		else
		{
			m_pData = m_pDefaultData = PSX_NULL;
		}

		/*if ( Initialize() != EErrorCode::NONE )
			PSX_PushError( "Failed to initialize ShaderConstant." );*/
	}

	ShaderConstant::~ShaderConstant( void )
	{
		PSX_SafeDeleteArray( m_pData );
		PSX_SafeDeleteArray( m_pDefaultData );
	}

	void ShaderConstant::SetSemantic( const CHAR *pSemantic )
	{
		GraphicsResourceManager *pGraphicsMan = GraphicsResourceManager::GetInstance();

		// Does it have a semantic?
		if ( pSemantic != PSX_NULL && PSX_StrCmp( pSemantic, PSX_String("") ) == 0 )
		{
			m_pSemantic = pGraphicsMan->GetShaderConstantSemantic( pSemantic );

			//if ( !m_pSemantic )
			//	return;

			//m_pDataType = pGraphicsMan->GetShaderConstantType( m_pSemantic->dataType );
		}
		else
		{
			//m_pDataType = pGraphicsMan->GetShaderConstantType( pType );
		}

		//if ( !m_bArray )
		//	m_dataCount = m_pDataType->dataCount;
	}
	
	//void ShaderConstant::Cleanup( void )
	//{
	//}

	void ShaderConstant::Update( void )
	{
		// Only constants with semantics are updatable
		if ( m_pSemantic == PSX_NULL )
			return;

		if ( m_pSemantic->semanticFunc )
			m_pSemantic->semanticFunc( m_pData, m_size );
	}
	
	void ShaderConstant::SetData( void *pData )
	{
		PSX_MemCopy( m_pData, pData, m_size );
	}
	
	void ShaderConstant::SetDefaultData( void *pData )
	{
		PSX_MemCopy( m_pDefaultData, pData, m_size );
	}
	
	void ShaderConstant::SetDefaultData( void *pData, SIZE_T count )
	{
		SIZE_T typeSize;

		switch( GetType() )
		{
		case EShaderConstantType::FLOAT:
			typeSize = sizeof(float);
			break;
		case EShaderConstantType::INT:
			typeSize = sizeof(int);
			break;
		case EShaderConstantType::BOOL:
			typeSize = sizeof(bool);
			break;
		}

		PSX_MemCopy( m_pDefaultData, pData, count * typeSize );
	}

}

#endif __PSX_WINDOWS_WINDOW
